﻿#include "TreeWidgetModel.h"
#include "TreeItemTypes.h"
#include "OperatorsInterface/TreeEventOperator.h"

#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKAppFramework/FITKRunTimeSetting.h"
#include "FITK_Kernel/FITKCore/FITKAbstractNDataObject.h"
#include "FITK_Component/FITKAcousticsModel/FITKAbstractSEASubSys.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsSEAModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsFEModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsFEFace.h"
#include "FITK_Component/FITKAcousticsModel/FITKAbstractFESubSys.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsSensors.h"
#include "FITK_Component/FITKAcousticsModel/FITKSEAAbstractJunction.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsGeometryData.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsPhysics.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsLoadManager.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbstractLoad.h"

#include <QTreeWidgetItem>

namespace GUI
{
    TreeWidgetModel::TreeWidgetModel(QWidget* parent /*= nullptr*/)
        :TreeWidgetPage(parent)
    {
        this->blockSignals(true);
        this->initTree();
        this->expandAll();
        this->blockSignals(false);
    }

    TreeWidgetType TreeWidgetModel::getTreeWidgetType()
    {
        return PageModel;
    }

    void TreeWidgetModel::updateModelTreeItemState()
    {
        QSignalBlocker blocker(this);
        
        //获取离散数据
        Acoustics::FITKAcousticsDiscModel* discModel = FITKAPP->getGlobalData()->getMeshData<Acoustics::FITKAcousticsDiscModel>();
        Acoustics::FITKAcousticsPhysics* physics = FITKAPP->getGlobalData()->getPhysicsData<Acoustics::FITKAcousticsPhysics>();
        if (discModel == nullptr)return;
        Acoustics::FITKAcousticsSEAModel* SEAModel = discModel->getSEAModel();
        Acoustics::FITKAcousticsFEModel* FEModel = discModel->getFEModel();
        if (SEAModel == nullptr || FEModel == nullptr)return;
        Acoustics::FITKAcousticsSEASubSysManager* SEASubSysManager = SEAModel->getSEASubSysManager();
        Acoustics::FITKJunctionManager* JunctionManager = discModel->getJunctionManager();
        Acoustics::FITKAcousticsFESubSysManager* FESubSysManager = FEModel->getFESubSysManager();
        Acoustics::FITKAcousticsFEFaceManager* FEFaceManager = FEModel->getFEFaceManager();
        Acoustics::FITKAcousticsSensorsManager* sensorManager = FEModel->getSensorManager();
        Acoustics::FITKAcousticsLoadManager* loadManager = physics->getFITKAcousticsLoadManager();
        if (!SEASubSysManager || !FESubSysManager || !JunctionManager || !FEFaceManager || !sensorManager || !loadManager) {
            return;
        }

        //修改item状态[局部函数]
        auto changeItemState = [](QTreeWidgetItem* item, bool state, QString runTimeTitle) {
            if (item) {
                if (state) {
                    item->setCheckState(0, Qt::Checked);
                }
                else {
                    item->setCheckState(0, Qt::Unchecked);
                }
            }

            // 保存配置。
            AppFrame::FITKRunTimeSetting* rtSettings = FITKAPP->getGlobalData()->getRunTimeSetting();
            if (rtSettings){
                rtSettings->setValue(runTimeTitle, state);
            }
        };

        //判断数据组的可见性[局部函数]
        auto judgeDatasEnable = [](QList<Core::FITKAbstractDataObject*> dataList)->bool {
            if (dataList.isEmpty())return true;
            for (Core::FITKAbstractDataObject* data : dataList) {
                if (data == nullptr)continue;
                if (data->isEnable() == true) {
                    return true;
                }
            }
            return false;
        };

        //更新几何节点
        QTreeWidgetItem* item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTGeoNodes);
        if (item) {
            QList<Interface::FITKAbsVirtualTopo*> dataList = getAllGeometryVirTopos(Interface::FITKGeoEnum::VTopoShapeType::VSPoint);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "GeomVertsVisibility");
        }

        //更新几何线
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTGeoCurve);
        if (item) {
            QList<Interface::FITKAbsVirtualTopo*> dataList = getAllGeometryVirTopos(Interface::FITKGeoEnum::VTopoShapeType::VSEdge);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "GeomEdgesVisibility");
        }

        //更新几何面
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTGeoSurface);
        if (item) {
            QList<Interface::FITKAbsVirtualTopo*> dataList = getAllGeometryVirTopos(Interface::FITKGeoEnum::VTopoShapeType::VSFace);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "GeomFacesVisibility");
        }

        //更新SEA梁
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTSEABeam);
        if (item) {
            QList<Acoustics::FITKAbstractSEASubSys*> dataList = SEASubSysManager->getSubSysByType(Acoustics::FITKAbstractSEASubSys::SEABeam);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "SEASubSystemBeamVisibility");
        }
        //更新SEA平板
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTSEAPlate);
        if (item) {
            QList<Acoustics::FITKAbstractSEASubSys*> dataList = SEASubSysManager->getSubSysByType(Acoustics::FITKAbstractSEASubSys::SEAFlatPlate);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "SEASubSystemFlatPlateVisibility");
        }
        //更新SEA单曲率半
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTSEASingleCurPlate);
        if (item) {
            QList<Acoustics::FITKAbstractSEASubSys*> dataList = SEASubSysManager->getSubSysByType(Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "SEASubSystemSingleCurPlateVisibility");
        }
        //更新SEA双曲率板
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTSEADoubleCurPlate);
        if (item) {
            QList<Acoustics::FITKAbstractSEASubSys*> dataList = SEASubSysManager->getSubSysByType(Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "SEASubSystemDoubleCurPlateVisibility");
        }
        //更新SEA声腔
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTSEAVocalCavity);
        if (item) {
            QList<Acoustics::FITKAbstractSEASubSys*> dataList = SEASubSysManager->getSubSysByType(Acoustics::FITKAbstractSEASubSys::SEACavity);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "SEASubSystemCavityVisibility");
        }
        //更新SEA半无限流体
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTSEASemiInfiniteFluids);
        if (item) {
            QList<Acoustics::FITKAbstractSEASubSys*> dataList = SEASubSysManager->getSubSysByType(Acoustics::FITKAbstractSEASubSys::SEASemiIInfiniteFluid);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "SEASubSystemSemiInfiniteFluidVisibility");
        }
        //更新FE面
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTFESurface);
        if (item) {
            QList<Acoustics::FITKAcousticsFEFace*> dataList = {};
            for (int i = 0; i < FEFaceManager->getDataCount(); i++) {
                dataList.append(FEFaceManager->getDataByIndex(i));
            }
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "FESurfaceVisibility");
        }
        //更新FE结构
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTFEStruct);
        if (item) {
            QList<Acoustics::FITKAbstractFESubSys*> dataList = FESubSysManager->
                getSubSysByType(Acoustics::FITKAbstractFESubSys::FESubSysType::FEStructure);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "FEStructVisibility");
        }
        //更新FE声腔
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTFEAcoustics);
        if (item) {
            QList<Acoustics::FITKAbstractFESubSys*> dataList = FESubSysManager->
                getSubSysByType(Acoustics::FITKAbstractFESubSys::FESubSysType::FEAcoustic);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "FEAcousticsVisibility");
        }
        //更新传感器
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTSensor);
        if (item) {
            QList<Acoustics::FITKAcousticsSensors*> dataList = {};
            for (int i = 0; i < sensorManager->getDataCount(); i++) {
                dataList.append(sensorManager->getDataByIndex(i));
            }
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())),"SensorVisibility");
        }
        //更新SEA点连接
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTCPSEA);
        if (item) {
            QList<Acoustics::FITKAbstractJunction*> dataList = JunctionManager->getJointsByType(Acoustics::FITKAbstractJunction::JunctionType::SEAPointJunction);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "SEAJunctionPointsVisibility");
        }
        //更新SEA线连接
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTCCSEA);
        if (item) {
            QList<Acoustics::FITKAbstractJunction*> dataList = JunctionManager->getJointsByType(Acoustics::FITKAbstractJunction::JunctionType::SEALineJunction);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "SEAJunctionLinesVisibility");
        }
        //更新SEA面连接
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTCSSEA);
        if (item) {
            QList<Acoustics::FITKAbstractJunction*> dataList = JunctionManager->getJointsByType(Acoustics::FITKAbstractJunction::JunctionType::SEAAreaJunction);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "SEAJunctionAreasVisibility");
        }
        //更新power在SEA梁上的载荷
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTLPBeam);
        if (item) {
            QList<Acoustics::FITKAcousticsAbstractLoad*> dataList = loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::PowerSEABeam);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "");
        }
        //更新power在SEA板上的载荷
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTLPShell);
        if (item) {
            QList<Acoustics::FITKAcousticsAbstractLoad*> dataList = loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::PowerSEAShell);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "");
        }
        //更新power在SEA声腔上的载荷
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTLPAcoustic);
        if (item) {
            QList<Acoustics::FITKAcousticsAbstractLoad*> dataList = loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::PowerSEAAcoustic);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "");
        }
        //更新power在FE上的载荷
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTLPFESubsystem);
        if (item) {
            QList<Acoustics::FITKAcousticsAbstractLoad*> dataList = loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::PowerFESubsys);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "");
        }
        //更新力与力矩在载荷
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTLForceMoment);
        if (item) {
            QList<Acoustics::FITKAcousticsAbstractLoad*> dataList = loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::ExcitationForceMoments);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "LoadPointSourceVisibility");
        }
        //更新Constraint在SEA梁上的载荷
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTLCBeam);
        if (item) {
            QList<Acoustics::FITKAcousticsAbstractLoad*> dataList = loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::ConstraintSEABeam);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "");
        }
        //更新Constraint在SEA板上的载荷
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTLCShell);
        if (item) {
            QList<Acoustics::FITKAcousticsAbstractLoad*> dataList = loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::ConstraintSEAShell);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "");
        }
        //更新Constraint在SEA声腔上的载荷
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTLCAcoustic);
        if (item) {
            QList<Acoustics::FITKAcousticsAbstractLoad*> dataList = loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::ConstraintSEAAcoustic);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "");
        }
        //更新Constraint在FE上的载荷
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTLCFESubsystem);
        if (item) {
            QList<Acoustics::FITKAcousticsAbstractLoad*> dataList = loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::ConstraintFESubsys);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "");
        }
        //更新HVNC载荷
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::MTHVACNoise);
        if (item) {
            QList<Acoustics::FITKAcousticsAbstractLoad*> dataList = loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::ImportNoiseHVAC);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "LoadHVACNoiseVisibility");
        }
        //更新单极子载荷
        item = TreeWidgetPage::getTreeWidgetItemByType(this, (int)ModelTreeItemsType::Monopole);
        if (item) {
            QList<Acoustics::FITKAcousticsAbstractLoad*> dataList = loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::ExcitationMonopole);
            changeItemState(item, judgeDatasEnable(QList<Core::FITKAbstractDataObject*>(dataList.begin(), dataList.end())), "LoadMonopoleVisibility");
        }
    }

    void TreeWidgetModel::initTree()
    {
        //导入的CAD/FE模型
        QTreeWidgetItem* iCAD_FEModelTreeRoot = this->CreateTreeRootItem(this, tr("Import CAD/FE Geometry"), (int)ModelTreeItemsType::MTImportCAD_FEModels, "", 1);
        //可视对象上的节点
        QTreeWidgetItem* graphObjNodeTreeRoot = this->CreateTreeRootItem(this, tr("Nodes on Visible Objects"), (int)ModelTreeItemsType::MTGraphObjectNodes, "", 1);
        graphObjNodeTreeRoot->setCheckState(0, Qt::Unchecked);

        //未使用的节点
        QTreeWidgetItem* unusedNodeTreeRoot = this->CreateTreeRootItem(this, tr("Unused Nodes"), (int)ModelTreeItemsType::MTUnusedNodes, "", 1);
        unusedNodeTreeRoot->setCheckState(0, Qt::Unchecked);

        //未使用的节点
        QTreeWidgetItem* nodeLabelsRoot = this->CreateTreeRootItem(this, tr("Node Labels"), (int)ModelTreeItemsType::MTNodeLabels, "", 1);
        nodeLabelsRoot->setCheckState(0, Qt::Unchecked);

        //几何树根节点
        QTreeWidgetItem* geometryTreeRoot = this->CreateTreeRootItem(this, tr("Geometry"), (int)ModelTreeItemsType::MTGeometryRoot, "", 1);
        //几何的子节点
        this->CreateTreeItem(geometryTreeRoot, tr("Points"), (int)ModelTreeItemsType::MTGeoNodes, "", 1);
        this->CreateTreeItem(geometryTreeRoot, tr("Curves"), (int)ModelTreeItemsType::MTGeoCurve, "", 1);
        this->CreateTreeItem(geometryTreeRoot, tr("Surfaces"), (int)ModelTreeItemsType::MTGeoSurface, "", 1);
        this->CreateTreeItem(geometryTreeRoot, tr("Solids"), (int)ModelTreeItemsType::MTGeoSolid, "", 1);

        //子系统根节点
        QTreeWidgetItem* subSystemTreeRoot = this->CreateTreeRootItem(this, tr("SubSystem"), (int)ModelTreeItemsType::MTSubSystemRoot, "", 1);
        //SEA系统的子节点
        QTreeWidgetItem* seaSys = this->CreateTreeItem(subSystemTreeRoot, tr("SEA"), (int)ModelTreeItemsType::MTSSSEARoot, "", 1);
        this->CreateTreeItem(seaSys, tr("Beam"), (int)ModelTreeItemsType::MTSEABeam, "", 1);
        QTreeWidgetItem* seaShell = this->CreateTreeItem(seaSys, tr("Shell"), (int)ModelTreeItemsType::MTSEAShell, "", 1);
        this->CreateTreeItem(seaShell, tr("Plate"), (int)ModelTreeItemsType::MTSEAPlate, "", 1);
        this->CreateTreeItem(seaShell, tr("Single Curvature Shell"), (int)ModelTreeItemsType::MTSEASingleCurPlate, "", 1);
        this->CreateTreeItem(seaShell, tr("Double Curvature Shell"), (int)ModelTreeItemsType::MTSEADoubleCurPlate, "", 1);

        this->CreateTreeItem(seaSys, tr("Acoustic Cavity"), (int)ModelTreeItemsType::MTSEAVocalCavity, "", 1);
        this->CreateTreeItem(seaSys, tr("Semi-Infinite Fluid"), (int)ModelTreeItemsType::MTSEASemiInfiniteFluids, "", 1);
        //FE系统的子节点
        QTreeWidgetItem* feSys = this->CreateTreeItem(subSystemTreeRoot, tr("FE"), (int)ModelTreeItemsType::MTSSFERoot, "", 1);
        this->CreateTreeItem(feSys, tr("FE Face"), (int)ModelTreeItemsType::MTFESurface, "", 1);
        this->CreateTreeItem(feSys, tr("FE Structure"), (int)ModelTreeItemsType::MTFEStruct, "", 1);
        this->CreateTreeItem(feSys, tr("FE Acoustic"), (int)ModelTreeItemsType::MTFEAcoustics, "", 1);
        //传感器系统
        this->CreateTreeItem(subSystemTreeRoot, tr("Sensor"), (int)ModelTreeItemsType::MTSensor, "", 1);

        //连接根节点
        QTreeWidgetItem* connectTreeRoot = this->CreateTreeRootItem(this, tr("Junction"), (int)ModelTreeItemsType::MTConnectRoot, "", 1);
        //连接点的子节点
        QTreeWidgetItem* pConnect = this->CreateTreeItem(connectTreeRoot, tr("Point"), (int)ModelTreeItemsType::MTCPointRoot, "", 1);
        this->CreateTreeItem(pConnect, tr("SEA"), (int)ModelTreeItemsType::MTCPSEA, "", 1);
        this->CreateTreeItem(pConnect, tr("Hybrid"), (int)ModelTreeItemsType::MTCPMix, "", 1);
        this->CreateTreeItem(pConnect, tr("FE"), (int)ModelTreeItemsType::MTCPFE, "", 1);
        //连接线的子节点
        QTreeWidgetItem* cConnect = this->CreateTreeItem(connectTreeRoot, tr("Line"), (int)ModelTreeItemsType::MTCCurveRoot, "", 1);
        this->CreateTreeItem(cConnect, tr("SEA"), (int)ModelTreeItemsType::MTCCSEA, "", 1);
        this->CreateTreeItem(cConnect, tr("Hybrid"), (int)ModelTreeItemsType::MTCCMix, "", 1);
        this->CreateTreeItem(cConnect, tr("FE"), (int)ModelTreeItemsType::MTCCFE, "", 1);
        //连接面的子节点
        QTreeWidgetItem* sConnect = this->CreateTreeItem(connectTreeRoot, tr("Area"), (int)ModelTreeItemsType::MTCSurfaceRoot, "", 1);
        this->CreateTreeItem(sConnect, tr("SEA"), (int)ModelTreeItemsType::MTCSSEA, "", 1);
        this->CreateTreeItem(sConnect, tr("Hybrid"), (int)ModelTreeItemsType::MTCSMix, "", 1);
        this->CreateTreeItem(sConnect, tr("FE"), (int)ModelTreeItemsType::MTCSFE, "", 1);

        //载荷根节点
        QTreeWidgetItem* loadTreeRoot = this->CreateTreeRootItem(this, tr("Load"), (int)ModelTreeItemsType::MTLoadRoot, "", 1);
        //载荷的子节点
        QTreeWidgetItem* LoadPower=this->CreateTreeItem(loadTreeRoot, tr("Power"), (int)ModelTreeItemsType::MTLPower, "", 1);
        //载荷Power的子节点
        this->CreateTreeItem(LoadPower, tr("Beam"), (int)ModelTreeItemsType::MTLPBeam, "", 1);
        this->CreateTreeItem(LoadPower, tr("Shell"), (int)ModelTreeItemsType::MTLPShell, "", 1);
        this->CreateTreeItem(LoadPower, tr("Acoustic"), (int)ModelTreeItemsType::MTLPAcoustic, "", 1);
        this->CreateTreeItem(LoadPower, tr("FE Subsystems"), (int)ModelTreeItemsType::MTLPFESubsystem, "", 1);

        this->CreateTreeItem(loadTreeRoot, tr("Point Force & Moments"), (int)ModelTreeItemsType::MTLForceMoment, "", 1);
        QTreeWidgetItem* LoadConstraint = this->CreateTreeItem(loadTreeRoot, tr("Constraint"), (int)ModelTreeItemsType::MTLConstraint, "", 1);
        //载荷Constraint的子节点
        this->CreateTreeItem(LoadConstraint, tr("Beam"), (int)ModelTreeItemsType::MTLCBeam, "", 1);
        this->CreateTreeItem(LoadConstraint, tr("Shell"), (int)ModelTreeItemsType::MTLCShell, "", 1);
        this->CreateTreeItem(LoadConstraint, tr("Acoustic"), (int)ModelTreeItemsType::MTLCAcoustic, "", 1);
        this->CreateTreeItem(LoadConstraint, tr("FE Subsystems"), (int)ModelTreeItemsType::MTLCFESubsystem, "", 1);

        this->CreateTreeItem(loadTreeRoot, tr("HVACNoise"), (int)ModelTreeItemsType::MTHVACNoise, "", 1);
        this->CreateTreeItem(loadTreeRoot, tr("Monopole"), (int)ModelTreeItemsType::Monopole, "", 1);

        //坐标系
        QTreeWidgetItem* coordinateSystemTreeRoot = this->CreateTreeRootItem(this, tr("Global Axes"), (int)ModelTreeItemsType::MTCoordinateSystem, "", 1);
    }

    void TreeWidgetModel::on_itemClicked(QTreeWidgetItem *item, int column)
    {
        Oper::TreeEventOperator* toper = this->getOperatorT<Oper::TreeEventOperator>("OperModelTreeEvent");
        if (toper == nullptr)return;
        toper->itemClicked(item, column);
    }

    void TreeWidgetModel::on_itemDoubleClicked(QTreeWidgetItem *item, int column)
    {
        Oper::TreeEventOperator* toper = this->getOperatorT<Oper::TreeEventOperator>("OperModelTreeEvent");
        if (toper == nullptr)return;
        toper->itemDouleClicked(item, column);
    }

    void TreeWidgetModel::on_itemStateChanged(QTreeWidgetItem *item, bool state, int column)
    {
        Oper::TreeEventOperator* toper = this->getOperatorT<Oper::TreeEventOperator>("OperModelTreeEvent");
        if (toper == nullptr)return;
        toper->itemStateChanged(item, state, column);
    }

    QList<Interface::FITKAbsVirtualTopo*> TreeWidgetModel::getAllGeometryVirTopos(Interface::FITKGeoEnum::VTopoShapeType type)
    {
        QList<Interface::FITKAbsVirtualTopo*> virTopoList = {};
        Acoustics::FITKAcousticsGeometryData* geometryData = FITKAPP->getGlobalData()->getGeometryData<Acoustics::FITKAcousticsGeometryData>();
        if (geometryData == nullptr) {
            return virTopoList;
        }

        //获取所有的集合命令
        QList<Interface::FITKAbsGeoCommand*> allGeo = {};
        const int n = geometryData->getDataCount();
        for (int i = 0; i < n; ++i) {
            Interface::FITKAbsGeoCommand* geo = geometryData->getDataByIndex(i);
            if (geo == nullptr) {
                continue;
            }
            allGeo.append(geo);
        }

        //获取虚拓扑
        for (Interface::FITKAbsGeoCommand* geoCom : allGeo) {
            if (geoCom == nullptr) {
                continue;
            }

            Interface::FITKShapeVirtualTopoManager* virTopoManager = geoCom->getShapeVirtualTopoManager(type);
            if (virTopoManager != nullptr) {
                for (int i = 0; i < virTopoManager->getDataCount(); i++) {
                    virTopoList.append(virTopoManager->getDataByIndex(i));
                }
            }
        }
        return virTopoList;
    }
}


